﻿using AbpApplication.Expand;
using AbpApplication.Flurl;
using AbpEntityFrameworkcore.DbContext;
using AbpToDomain.EntityInfo;
using Application.Expand;
using JetBrains.Annotations;
using Mesosphere.Dto;
using Mesosphere.InPut;
using Microsoft.EntityFrameworkCore;
using System.Reflection.Emit;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;

namespace AbpApplication.AppServices
{
    public class ConsumerService : ApplicationService, IConsumerService
    {

        private readonly IRepository<TaskOrder> taskorder_res;
        private readonly IRepository<NeetOutMaterial> neetout_res;
        private readonly IRepository<MaterialBase> material_res;
        private readonly IRepository<NeetOutMaterial> neetoutmaterial_res;
        private readonly IRepository<PutInOrder> put_in_res;
        private readonly IRepository<PutOutOrder> put_out_res;
        private readonly IRepository<BoxPosition> boxPosition_res;
        private readonly IRepository<WarehouseLine> WarehouseLine_res;
        private readonly IRepository<Box> box_res;
        private readonly IRepository<lognote> log_res;
        private readonly IRepository<BoxType> boxtype_res;
        private readonly IToOutSideInterFace toOutSideInterFace;
        private readonly MyDbContext dbContext;
        private readonly IRepository<MaterialProperty> MaterialProperty_res;

        private readonly ILoginHelper loginHelper;

        public ConsumerService(IRepository<TaskOrder> taskorder_res,
            IRepository<NeetOutMaterial> neetout_res,
            IRepository<MaterialBase> material_res,
            IRepository<NeetOutMaterial> neetoutmaterial_res, ILoginHelper loginHelper,
IRepository<MaterialProperty> materialProperty_res, IRepository<PutInOrder> put_in_res,
MyDbContext dbContext, IRepository<PutOutOrder> put_out_res, IRepository<Box> box_res,
IRepository<WarehouseLine> warehouseLine_res, IToOutSideInterFace toOutSideInterFace, IRepository<BoxPosition> boxPosition_res, IRepository<lognote> log_res, IRepository<BoxType> boxtype_res)

        {
            this.taskorder_res = taskorder_res;
            this.neetout_res = neetout_res;
            this.material_res = material_res;
            this.neetoutmaterial_res = neetoutmaterial_res;
            this.loginHelper = loginHelper;
            MaterialProperty_res = materialProperty_res;
            this.put_in_res = put_in_res;
            this.dbContext = dbContext;
            this.put_out_res = put_out_res;
            this.box_res = box_res;

            WarehouseLine_res = warehouseLine_res;
            this.toOutSideInterFace = toOutSideInterFace;
            this.boxPosition_res = boxPosition_res;
            this.log_res = log_res;
            this.boxtype_res = boxtype_res;
        }

        public async Task<ApiResponse> CreateInBoundOrder(InPut_CunsumerService InPut)//创建入库
        {
            try
            {

               bool isSymbolExists = await put_in_res.AnyAsync(x => x.Symbol == InPut.Symbol);
                if (isSymbolExists)
                {
                    return new ApiResponse("该任务id已存在", false, null);
                }

                Box box = await box_res.FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode);
                if (box == null)
                {
                    return new ApiResponse("料盒不存在", false, null);
                }
                if (box.Id_WarehouseLine != null)
                {
                    return new ApiResponse("料盒已经上架,无法再次执行", false, null);
                }
                BoxType boxType = await boxtype_res.FirstOrDefaultAsync(x => x.BoxType_Name.Contains(InPut.putInOrderDtos[0].MaterialName));
                if (boxType == null)
                {
                    return new ApiResponse("未查询到料盒类型", false, null);
                }
                WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.IsOccupy == false&&x.Box==null&&(x.BoxType==boxType||x.BoxType.BoxType_Name=="混放区"));
                if (warehouseLine == null)
                {
                    return new ApiResponse("库位已满", false, null);
                }
                bool TaskCheckres= await taskorder_res.AnyAsync(x=>x.Box.BoxCode==InPut.BoxCode);
                if (TaskCheckres)
                {
                    return new ApiResponse("该料盒任务已存在任务", false, null);
                }
        

                //create putinorder
                List<PutInOrder> putInOrderModel = new List<PutInOrder>();
                foreach (var item in InPut.putInOrderDtos)
                {
                    PutInOrder putInOrder = new PutInOrder();
                    putInOrder.Symbol = InPut.Symbol;
                    putInOrder.MaterialCode = item.MaterialCode;
                    putInOrder.Quantity = item.Quantity;
                    putInOrder.MaterilaryName = item.MaterialName;
                    putInOrder.CreateTime = DateTime.Now;
                    putInOrder.State = "已入库";
                    putInOrderModel.Add(putInOrder);
                }
                 //create materialbase  update boxposition  create lognote
                  var boxPositions = await boxPosition_res.GetListAsync(x => x.BoxPositionCode.Contains(InPut.BoxCode));
                  List<MaterialBase> materialBases = new List<MaterialBase>();
                  List<lognote> lognotes = new List<lognote>();
                   foreach (var material in InPut.putInOrderDtos)
                    {
                    BoxPosition boxPosition = boxPositions.FirstOrDefault(x => x.MaterialBase==null);
                    if (boxPosition == null)
                    {
                        return new ApiResponse("料盒已满", false, null);
                    }
                        MaterialBase materialBase = new MaterialBase();
                        materialBase.MaterialCode = material.MaterialCode;
                        materialBase.MaterialuniqueCode=ExtendRandom.CreateRandom();
                        materialBase.MaterialName = material.MaterialName;
                        materialBase.Quantity = material.Quantity;
                        materialBase.BoxPosition = boxPosition;
                        materialBase.CreatedDate = DateTime.Now;
                        materialBase.Consumer_MaterialId = InPut.Symbol;
                        boxPosition.MaterialBase = materialBase;
                        materialBases.Add(materialBase);
                        lognote log = new lognote() { User="mes",Type="入库",DateTime=DateTime.Now,Note=$"{material.MaterialCode}-{material.Quantity}-{material.MaterialName}-{boxPosition}" };
                        lognotes.Add(log);  
                }

                //create taskorder  
                TaskOrder taskOrder = new TaskOrder();
                taskOrder = taskOrder.AddTaskOrder("入库", box, warehouseLine.WarehouseLineCode, InPut.Machine, InPut.Symbol, null, null, "已下发");
                //update warehouseLine
                warehouseLine.IsOccupy = true;
                //update box
                box.BoxType = boxType;
                //send taskorder
                Ess_Input ess_Input = new Ess_Input();
                ess_Input.taskType = "putaway";
                ess_Input.taskGroupCode = $"taskGroupCode-{taskOrder.taskPriority}";
                ess_Input.groupPriority = taskOrder.groupPriority;
                List<Tasks> data = new List<Tasks>();
                Tasks ta = new Tasks();
                ta.taskCode = taskOrder.TaskOrderCode;
                data.Add(ta);
                ess_Input.tasks = data;
                TaskDescribe td = new TaskDescribe();
                td.containerCode = taskOrder.Box.BoxCode;
                td.containerType = "CT_KUBOT_STANDARD";
                td.storageTag = "";
                td.fromLocationCode = taskOrder.InlethouseCode; 
                td.toLocationCode = taskOrder.WarehouseCode;
                td.toStationCode = "haiport_station_1";
                td.isPutaway = false;
                ta.taskDescribe = td;
                string res = await toOutSideInterFace.CreateTask(ess_Input);
                if (res.Contains("OK")) 
                {
                   
                    await put_in_res.InsertManyAsync(putInOrderModel);
                    await material_res.InsertManyAsync(materialBases);
                    await boxPosition_res.UpdateManyAsync(boxPositions);
                    await WarehouseLine_res.UpdateAsync(warehouseLine);
                    await taskorder_res.InsertAsync(taskOrder);
                    await log_res.InsertManyAsync(lognotes);
                    await box_res.UpdateAsync(box);
                    return new ApiResponse("入库成功,已发送AGV任务", true, null);
                }
                return new ApiResponse("入库失败", false, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, $"Error-CreateInBoundOrder+{ex}");
                return new ApiResponse("Error-CreateInBoundOrder", false, null);
            }
        }

        public async Task<ApiResponse> CreateOutBoundOrder(InPut_CunsumerService2 InPut)
        {
            try
            {

                Box box = await box_res.FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode);
                if (box == null)
                {
                    return new ApiResponse("料盒不存在", false, null);
                }
                WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.Box == box);
                if (warehouseLine == null)
                {
                    return new ApiResponse("未查询到料盒", false, null);
                }
                //create putorder
                PutOutOrder putOutOrder = new PutOutOrder();
                putOutOrder.Symbol = InPut.Symbol;
                //create taskorder  
                TaskOrder taskOrder = new TaskOrder();
                taskOrder = taskOrder.AddTaskOrder("出库", box, warehouseLine.WarehouseLineCode, "LT_CONVEYOR_INPUT:POINT:1562:2833", InPut.Symbol, null, null,"已下发");
                //send taskorder
                Ess_Input ess_Input = new Ess_Input();
                ess_Input.taskType = "carry";
                ess_Input.taskGroupCode = $"taskGroupCode-{taskOrder.taskPriority}";
                ess_Input.groupPriority = taskOrder.groupPriority;
                List<Tasks> data = new List<Tasks>();
                Tasks ta = new Tasks();
                ta.taskCode = taskOrder.TaskOrderCode;
                data.Add(ta);
                ess_Input.tasks = data;
                TaskDescribe td = new TaskDescribe();
                td.containerCode = taskOrder.Box.BoxCode;
                td.containerType = "CT_KUBOT_STANDARD";
                td.storageTag = "";
                td.fromLocationCode = taskOrder.WarehouseCode;
                td.toLocationCode = taskOrder.InlethouseCode;
                td.toStationCode = "haiport_station_1";
                td.isPutaway = false;
                ta.taskDescribe = td;
                //string res = await toOutSideInterFace.CreateTask(ess_Input);
                if (true)
                {
                    await taskorder_res.InsertAsync(taskOrder);
                    return new ApiResponse("出库成功,已发送AGV任务", true, null);
                }


                return new ApiResponse("添加成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "Error-CreateOutBoundOrder");
                return new ApiResponse("Error-CreateOutBoundOrder", false, null);
            }
        }//创建出库

        public async Task<ApiResponse> GetMaterialInfo(InPut_CunsumerService3 InPut)
        {
            throw new NotImplementedException();
        }

        public async Task<ApiResponse> MakeInventory(InPut_CunsumerService4 InPut)
        {
            throw new NotImplementedException();
        }
    }
}
